到底线程池应该设置多少合适?
点击上方蓝色字体,选择“设置星标”
优质文章,第一时间送达
图片来源:凤凰网
大家都写过多线程应用,也都用过线程池,那么线程池究竟设置多少个合适呢?
想必这个问题困恼着我们很多人,我们中的大部分都是拍着脑袋决定的。针对 CPU 密集型的程序比较简单我们就不讨论了,但是对于 IO 密集型的程序究竟设置多少合适呢?
我查阅了 《Java虚拟机并发编程》 里面提供了一个公式如下:「关注订阅号回复“并发编程”获取 PDF」
线程数 = CPU 核心数 *( 1 - IO 阻塞系数)
「网上的文章基本都是出自这本书,但是还写的鱼龙混杂,没头没尾,建议通读下这本书的第二章」
公式中提到的阻塞系数决定于你的程序的 IO 延迟程度,当然这也是需要通过经验评估出来的,下面的图呢就是一个具体例子测试情况,可以看出来线程池的大小对响应时间的比例,并不是线程越多越快,针对每一个程序都会有一个合适的点。当然这个公式给我们提供的是一个解决思路,并不是实际的数量,毕竟我们的程序的性能也是参差不齐的。所以我们需要参考上面的公式,结合自己程序的“阻塞”时间合理的评估一个数量。
图片来源:Java 虚拟机并发编程
为了更加深入理解这问题,我又查阅了极客时间最新的课程《Java并发编程实战》,里面也有讲到了一个公式,并且还配了一个图,可以更清晰的解释这个问题,它提供的是一个公式是:
线程数 = CPU 核心数 * ( 1 +(I/O 耗时 / CPU 耗时))
公式里面提到的 CPU 耗时我个人理解是业务逻辑部分需要的运行 CPU 的时间,并不是时间片的切换时间,因为纳秒级别的通常可以忽略。但是通常情况我们做多线程程序是把 CPU 的计算时间 + IO 的耗时逻辑放在一起的,所以如果你的程序也是这样的,那么你就需要注意一下了。
它用了一个图生动形象的解释了一下多线程任务是怎么切换的。由下图我们可以看到多个线程的切换,是不是更清晰的理解了多线程的运行原理?当然道理一样,具体的线程数还是得我们自己根据业务的上下文评估。书和极客时间的课程都是让我们更好的理解多线程,更好的评估。
图片来源:极客时间
说了这么多,简单的总结下,对于 IO 密集型程序,线程数通常情况下是 IO 耗时越久需要分配的线程数越多,这样每一个线程就可以快速的切换处理耗时的逻辑,以达到并行处理的效果。当然这个也不是无限大,因为要考虑带宽、磁盘的瓶颈。
对了,极客时间这个课程里面还是有很多干货的,我买了确实受益良多。比如内存的可见性、锁、各种并发包下面的关键字都有一个深入的剖析,并且最新的并发包下面的工具类也会进行介绍,确实值得一读。
极客时间这两天做活动原价 99 ,现在 79,有需要的可以通过下面的二维码购买,我会收到 24 元返现,可以加我微信 small_artisan 发截图给我,我会把返现直接转给你。也期待和你一起讨论多线程程序。
「小匠粉丝群」,小匠创建了一个「知识星球」里面有很多关于技术、求职、面试的困惑和经验,有兴趣的可以加入支持一下小匠。
往期精彩回顾
1、阿里社招面试指南